package cn.itsource.system.service.impl;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.itsource.system.domain.Logininfo;
import cn.itsource.system.domain.Menu;
import cn.itsource.system.jwt.JwtUtil;
import cn.itsource.system.jwt.Payload;
import cn.itsource.system.mapper.LogininfoMapper;
import cn.itsource.system.query.LogininfoQuery;
import cn.itsource.system.service.ILogininfoService;
import cn.itsource.until.JsonResult;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;


@Service
// Transactional：用来控制事务的注解；readOnly：只读；propagation：事务传播机制
//  Propagation.SUPPORTS：支持当前事务，如果没有当前事务，就以非事务方法执行
@Transactional(readOnly = true,propagation = Propagation.SUPPORTS)

public class LogininfoServiceImpl implements ILogininfoService {

    @Autowired
    private LogininfoMapper logininfoMapper;

    @Transactional
    @Override
    public void add(Logininfo logininfo) {
        // hutool生成的盐值和加密
        // RandomUtil.randomString 获得一个随机的字符串（只包含数字和字符） ，32位
        String salt = RandomUtil.randomString(32);
        //  SecureUtil.md5 加密
        String md5Psd = SecureUtil.md5(logininfo.getPassword() + salt);

        // 将员工信息添加到数据库
        logininfo.setSalt(salt);
        logininfo.setPassword(md5Psd);
        logininfoMapper.add(logininfo);

    }

    @Transactional
    @Override
    public void update(Logininfo logininfo) {
        // 将员工信息更新到数据库
        logininfoMapper.update(logininfo);



    }

    @Transactional
    @Override
    public void delete(Long id) {
       // 将从数据库中删除员工信息
        logininfoMapper.delete(id);
    }

    @Override
    public Logininfo getOne(Long id) {
        return logininfoMapper.getOne(id);
    }

    @Override
    public List<Logininfo> getAll() {
        return logininfoMapper.getAll();
    }

    @Transactional
    @Override
    public void patchDelete(Long[] ids) {
        for (Long id : ids) {
            delete(id);
        }
    }

    @Override
    public PageInfo<Logininfo> pageQuery(LogininfoQuery query) {
        //原生的写法：1.先查询总页数  2.再根据分页的信息查询当前页的数据
        //PageHelper的写法：开启分页
//                PageHelper.startPage(当前页,每页显示的条数);
        PageHelper.startPage(query.getCurrentPage(), query.getPageSize());
        //分页查询：只要开启了分页，它会帮助我们做什么事情？
        //1.先查询总数量  //2.根据application.yml中驱动名自动实现分页，如果是mysql就用limit
        //3.自动计算limit的第一个值：limit a,b [a = 当前页的起始下标 = (当前页-1)*每页显示的条数]
//        List<Emp> emps = empMapper.pageQuery(empQuery);
        List<Logininfo> list = logininfoMapper.pageQuery(query);

        return new PageInfo(list);
    }

    @Override
    public JsonResult login(Map<String, String> map) {
        // 获取前端传递的参数（这里获取的和前端要相互对应）
        String account = map.get("account");
        String password = map.get("password");
        String type = map.get("type");

        // 校验账号和密码是否为空值 —— hutool
        if (StrUtil.isBlank(account) && StrUtil.isBlank(password)){
            return JsonResult.error("账号或密码为空");
        }

        Logininfo logininfo = logininfoMapper.findAccount(account);
        if (logininfo == null){
            return JsonResult.error("账号不存在");
        }

        String inputPassword = SecureUtil.md5(password + logininfo.getSalt());
        if (!inputPassword.equals(logininfo.getPassword())){
            return JsonResult.error("密码错误");
        }

        Payload payload = new Payload();
        logininfo.setPassword(null);
        List<String> permissions = logininfoMapper.findPermissionsByLogininfoId(logininfo.getId());
        List<Menu> menus = logininfoMapper.findMenusByLogininfoId(logininfo.getId());
        payload.setLogininfo(logininfo);
        payload.setPermissions(permissions);
        payload.setMenus(menus);

        String jwtToken = JwtUtil.generateToken(payload);


        return JsonResult.success(jwtToken);
    }

}
